
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace CL
{
    public class CLEntitySystemSingleton :CLSingleton<CLEntitySystemSingleton>, ICLSingletonAwake
    {
        public CLTypeSystems TypeSystems { get; private set; }

        public void Awake()
        {
            this.TypeSystems = new CLTypeSystems(CLInstanceQueueIndex.Max);

            /*            foreach (Type type in CodeTypes.Instance.GetTypes(typeof(EntitySystemAttribute)))
                        {
                            SystemObject obj = (SystemObject)Activator.CreateInstance(type);

                            if (obj is ISystemType iSystemType)
                            {
                                TypeSystems.OneTypeSystems oneTypeSystems = this.TypeSystems.GetOrCreateOneTypeSystems(iSystemType.Type());
                                oneTypeSystems.Map.Add(iSystemType.SystemType(), obj);
                                int index = iSystemType.GetInstanceQueueIndex();
                                if (index > InstanceQueueIndex.None && index < InstanceQueueIndex.Max)
                                {
                                    oneTypeSystems.QueueFlag[index] = true;
                                }
                            }
                        }*/
           // CLLog.Info("CLEntitySystemSingleton Awake");
            //发送消息
            //JEvent.defaultEvent.Post(new LoadCLSystemType());
        }

        /*   public void Serialize(CLEntity component)
           {
               if (component is not ISerialize)
               {
                   return;
               }

               List<SystemObject> iSerializeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof(ISerializeSystem));
               if (iSerializeSystems == null)
               {
                   return;
               }

               foreach (ISerializeSystem serializeSystem in iSerializeSystems)
               {
                   if (serializeSystem == null)
                   {
                       continue;
                   }

                   try
                   {
                       serializeSystem.Run(component);
                   }
                   catch (Exception e)
                   {
                       UnityEngine.Debug.LogError(e);
                   }
               }
           }

           public void Deserialize(CLEntity component)
           {
               if (component is not IDeserialize)
               {
                   return;
               }

               List<SystemObject> iDeserializeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof(IDeserializeSystem));
               if (iDeserializeSystems == null)
               {
                   return;
               }

               foreach (IDeserializeSystem deserializeSystem in iDeserializeSystems)
               {
                   if (deserializeSystem == null)
                   {
                       continue;
                   }

                   try
                   {
                       deserializeSystem.Run(component);
                   }
                   catch (Exception e)
                   {
                       UnityEngine.Debug.LogError(e);
                   }
               }
           }

           // GetComponentSystem
           public void GetComponentSys(CLEntity entity, Type type)
           {
               List<CLSystemObject> iGetSystem = this.TypeSystems.GetSystems(entity.GetType(), typeof(IGetComponentSysSystem));
               if (iGetSystem == null)
               {
                   return;
               }

               foreach (IGetComponentSysSystem getSystem in iGetSystem)
               {
                   if (getSystem == null)
                   {
                       continue;
                   }

                   try
                   {
                       getSystem.Run(entity, type);
                   }
                   catch (Exception e)
                   {
                       UnityEngine.Debug.LogError(e);
                   }
               }
           }*/

        public void Awake(CLEntity component)
        {
            List<CLSystemObject> iAwakeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof(ICLAwakeSystem));
            if (iAwakeSystems == null)
            {
                return;
            }

            foreach (ICLAwakeSystem aAwakeSystem in iAwakeSystems)
            {
                if (aAwakeSystem == null)
                {
                    continue;
                }

                try
                {
                    aAwakeSystem.Run(component);
                }
                catch (Exception e)
                {
                    UnityEngine.Debug.LogError($"{e.Message}\n{e.Data["StackTrace"]}");
                }
            }
        }

        public void Awake<P1>(CLEntity component, P1 p1)
        {
            if (component is not ICLAwake<P1>)
            {
                return;
            }

            List<CLSystemObject> iAwakeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof(ICLAwakeSystem<P1>));
            if (iAwakeSystems == null)
            {
                return;
            }

            foreach (ICLAwakeSystem<P1> aAwakeSystem in iAwakeSystems)
            {
                if (aAwakeSystem == null)
                {
                    continue;
                }

                try
                {
                    aAwakeSystem.Run(component, p1);
                }
                catch (Exception e)
                {
                    UnityEngine.Debug.LogError($"{e.Message}\n{e.Data["StackTrace"]}");
                }
            }
        }

        public void Awake<P1, P2>(CLEntity component, P1 p1, P2 p2)
        {
            if (component is not ICLAwake<P1, P2>)
            {
                return;
            }

            List<CLSystemObject> iAwakeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof(ICLAwakeSystem<P1, P2>));
            if (iAwakeSystems == null)
            {
                return;
            }

            foreach (ICLAwakeSystem<P1, P2> aAwakeSystem in iAwakeSystems)
            {
                if (aAwakeSystem == null)
                {
                    continue;
                }

                try
                {
                    aAwakeSystem.Run(component, p1, p2);
                }
                catch (Exception e)
                {
                    UnityEngine.Debug.LogError($"{e.Message}\n{e.Data["StackTrace"]}");
                }
            }
        }

        public void Awake<P1, P2, P3>(CLEntity component, P1 p1, P2 p2, P3 p3)
        {
            if (component is not ICLAwake<P1, P2, P3>)
            {
                return;
            }

            List<CLSystemObject> iAwakeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof(ICLAwakeSystem<P1, P2, P3>));
            if (iAwakeSystems == null)
            {
                return;
            }

            foreach (ICLAwakeSystem<P1, P2, P3> aAwakeSystem in iAwakeSystems)
            {
                if (aAwakeSystem == null)
                {
                    continue;
                }

                try
                {
                    aAwakeSystem.Run(component, p1, p2, p3);
                }
                catch (Exception e)
                {
                    UnityEngine.Debug.LogError($"{e.Message}\n{e.Data["StackTrace"]}");
                }
            }
        }

        public void Destroy(CLEntity component)
        {
            if (component is not ICLDestroy)
            {
                return;
            }

            List<CLSystemObject> iDestroySystems = this.TypeSystems.GetSystems(component.GetType(), typeof(ICLDestroySystem));
            if (iDestroySystems == null)
            {
                return;
            }

            foreach (ICLDestroySystem iDestroySystem in iDestroySystems)
            {
                if (iDestroySystem == null)
                {
                    continue;
                }

                try
                {
                    iDestroySystem.Run(component);
                }
                catch (Exception e)
                {
                    UnityEngine.Debug.LogError($"{e.Message}\n{e.Data["StackTrace"]}");
                }
            }
        }


        //加载dCLSystemType
        public void LoadCLSystemType(Type type)
        {
            CLSystemObject obj = (CLSystemObject)Activator.CreateInstance(type);
            if (obj is ICLSystemType iSystemType)
            {
                CLTypeSystems.CLOneTypeSystems oneTypeSystems = this.TypeSystems.GetOrCreateOneTypeSystems(iSystemType.Type());
                //oneTypeSystems.Map.Add(iSystemType.SystemType(), obj);
                List<CLSystemObject> list;
                oneTypeSystems.Map.TryGetValue(iSystemType.SystemType(), out list);
                if (list == null)
                {
                    list = new List<CLSystemObject>();
                    oneTypeSystems.Map[iSystemType.SystemType()] = list;
                }
                list.Add(obj);
                int index = iSystemType.GetInstanceQueueIndex();
                if (index > CLInstanceQueueIndex.None && index < CLInstanceQueueIndex.Max)
                {
                    oneTypeSystems.QueueFlag[index] = true;
                }
            }
        }


    }
}
